package com.ky.manage.permission;

import android.app.Activity;
import android.app.AppOpsManager;
import android.app.NotificationManager;
import android.content.ActivityNotFoundException;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.os.Binder;
import android.os.Build;
import android.provider.MediaStore;
import android.provider.Settings;
import android.text.Spannable;
import android.text.style.AbsoluteSizeSpan;
import android.text.style.ForegroundColorSpan;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;

import com.ky.manage.BaseApplication;
import com.ky.manage.R;
import com.ky.manage.activityLifecycle.ActivityManagerUtil;
import com.ky.manage.utils.ScreenUtils;
import com.ky.manage.utils.Spanny;
import com.ky.manage.utils.StringUtil;
import com.ky.manage.utils.ToastUtils;
import com.snail.permission.AndPermission;
import com.snail.permission.fileProvider.SnailFileProviderUtils;
import com.snail.permission.runtime.Permission;

import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;


/**
 * AndPermission github: https://github.com/yanzhenjie/AndPermission.git
 * 权限相关工具类
 *
 * @author zhaoyan
 * @date 2019-03-18
 */
public class AndPermissionUtils {

    /**
     * 跳转系统设置页的request code
     */
    public static final int REQUEST_CODE_SETTING = 1;
    public static final int REQUEST_CODE_WRITE_SETTINGS = 2;
    public static final int KEEP_APP_ALIVE_REQ_CODE = 10;
    private static final String TAG = AndPermissionUtils.class.getSimpleName();
    private static final String OP_POST_NOTIFICATION = "OP_POST_NOTIFICATION";
    private static final String CHECK_OP_NO_THROW = "checkOpNoThrow";
    private static final int MODE_ASK = 4;
    private static final String OP_WRITE_SETTINGS = "OP_WRITE_SETTINGS";
    private static AndPermissionUtils andPermissionUtils;
    /**
     * app所有权限:读写，设备，相机，定位,打电话
     */
    private static String[] ALL_PERMISSIONS = {
            Permission.READ_EXTERNAL_STORAGE,
            Permission.WRITE_EXTERNAL_STORAGE,
//            Permission.READ_PHONE_STATE,
            Permission.CAMERA,
            Permission.ACCESS_COARSE_LOCATION,
            Permission.ACCESS_FINE_LOCATION,
            Permission.CALL_PHONE
    };
    /**
     * GPS定位相关权限
     */
    private static String[] GPS_LOCATION_PERMISSIONS = {
            Permission.ACCESS_COARSE_LOCATION,
            Permission.ACCESS_FINE_LOCATION,
            Permission.READ_EXTERNAL_STORAGE,
            Permission.WRITE_EXTERNAL_STORAGE,
            Permission.READ_PHONE_STATE
    };
    /**
     * 引导设置弹框
     */
    private PermissionDialog mPermissionGuideDialog;
    /**
     * 悬浮提示弹框
     */
    private PermissionDialog mOverlayGuideDialog;
    private NotificationManager mNotificationManager;

    /*************************************业务相关*********************************/
    private AppOpsManager mAppOpsManager;
    private int mTargetSdkVersion;
    private String mPackageName;

    private AndPermissionUtils() {

    }

    public static AndPermissionUtils getInstance() {
        if (null == andPermissionUtils) {
            synchronized (AndPermissionUtils.class) {
                if (null == andPermissionUtils) {
                    andPermissionUtils = new AndPermissionUtils();
                }
            }
        }
        return andPermissionUtils;
    }

    /**
     * 获取权限
     *
     * @param context
     * @param requestListener 权限授权结果监听
     * @param showGuideDialog 是否引导权限设置
     * @param permissionGroup 权限申请组
     */
    public void requestPermission(final Context context,
                                  final PermissionRequestListener requestListener,
                                  final boolean showGuideDialog,
                                  final String... permissionGroup) {
        if (null == context || null == permissionGroup || permissionGroup.length == 0) {
            return;
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            List<String> deniedPermissions = getDeniedPermissions(context, permissionGroup);
            if (null == deniedPermissions || deniedPermissions.isEmpty()) {
                if (null != requestListener) {
                    requestListener.onGranted();
                }
                return;
            }
            String[] deniedPermissionArr = new String[deniedPermissions.size()];
            deniedPermissions.toArray(deniedPermissionArr);
            doReqPermission(context, requestListener, showGuideDialog, permissionGroup);
        } else {
            if (null != requestListener) {
                requestListener.onGranted();
            }
        }
    }

    /**
     * 申请权限
     *
     * @param context
     * @param requestListener
     * @param showGuideDialog
     * @param permissionGroup
     */
    private void doReqPermission(final Context context,
                                 final PermissionRequestListener requestListener,
                                 final boolean showGuideDialog,
                                 final String... permissionGroup) {
        if (null == permissionGroup || permissionGroup.length == 0) {
            return;
        }
        // 没有权限，申请权限
        AndPermission.with(context)
                .runtime()
                .permission(permissionGroup)
                .onGranted(data -> {
                    //避免兼容性问题，真实授权状态跟回调不一致的情况，避免崩溃
                    final List<String> deniedPermissionGroup = getDeniedPermissions(context, permissionGroup);
                    if (null == deniedPermissionGroup || deniedPermissionGroup.isEmpty()) {
                        if (requestListener != null) {
                            requestListener.onGranted();
                        }
                    } else {
                        permissionGuide(context, requestListener, showGuideDialog, deniedPermissionGroup);
                    }
                })
                .onDenied(data -> {
                    //避免兼容性问题，真实授权状态跟回调不一致的情况
                    final List<String> deniedPermissionGroup = getDeniedPermissions(context, permissionGroup);
                    if (null == deniedPermissionGroup || deniedPermissionGroup.isEmpty()) {
                        if (requestListener != null) {
                            requestListener.onGranted();
                        }
                        return;
                    }
                    //针对用户点了不再提示这种情况
                    if (AndPermission.hasAlwaysDeniedPermission(context, deniedPermissionGroup)) {
                        //替换为自己的对话框
                        permissionGuide(context, requestListener, showGuideDialog, deniedPermissionGroup);
                    } else {
                        toastGrantPermissionFail();
                        requestListener.onDenied(deniedPermissionGroup);
                    }
                }).start();
    }

    /**
     * toast提示授权失败
     */
    private void toastGrantPermissionFail() {
        ToastUtils.showRoundRectToast(StringUtil.getResString(R.string.permission_grant_fail));
    }

    /**
     * 获取未授权的权限（包含勾选禁止询问的权限）
     *
     * @param context
     * @param permissionGroup
     * @return
     */
    private List<String> getDeniedPermissions(Context context, String[] permissionGroup) {
        if (null == permissionGroup || permissionGroup.length == 0) {
            return null;
        }
        List<String> deniedPermissions = new ArrayList<>();
        for (String permission : permissionGroup) {
            if (!AndPermission.hasPermissions(context, permission)) {
                deniedPermissions.add(permission);
            }
        }
        return deniedPermissions;
    }

    /**
     * 权限设置引导弹框
     *
     * @param context
     * @param requestListener
     * @param showGuideDialog
     * @param deniedPermissionGroup
     */
    private void permissionGuide(final Context context,
                                 final PermissionRequestListener requestListener,
                                 final boolean showGuideDialog,
                                 final List<String> deniedPermissionGroup) {
        if (null == deniedPermissionGroup || deniedPermissionGroup.isEmpty()) {
            return;
        }
        if (!showGuideDialog) {
            toastGrantPermissionFail();
            if (requestListener != null) {
                requestListener.onDenied(deniedPermissionGroup);
            }
            return;
        }
        //设置引导
        if (context instanceof Activity && !((Activity) context).isFinishing()) {
            if (null == mPermissionGuideDialog || null == mPermissionGuideDialog.getDialog()) {
                mPermissionGuideDialog = new PermissionDialog(context, -1)
                        .setDialogLayout(R.layout.dialog_permission_guide)
                        .setCancelable(false)
                        .setDismissListener(dialog -> {
                            //对话框关闭监听
                            if (null != mPermissionGuideDialog) {
                                mPermissionGuideDialog.resetDialogView();
                                mPermissionGuideDialog = null;
                            }
                        });
            }
            mPermissionGuideDialog.setDialogViewListener((v, baseDialog) -> {
                //设置view内容
                TextView contentTv = v.findViewById(R.id.dialog_content);
                contentTv.setText(getPermissionGuideMsg(deniedPermissionGroup));
                //对话框view绑定事件监听
                v.findViewById(R.id.posButton).setOnClickListener(v1 -> {
                    //去设置
                    //在activity onActivityResult监听回来事件
                    AndPermission.with(context)
                            .runtime()
                            .setting().start(REQUEST_CODE_SETTING);
                    baseDialog.dismiss();
                });
            }).show();
        } else {
            //取消
            toastGrantPermissionFail();
            if (requestListener != null) {
                requestListener.onDenied(deniedPermissionGroup);
            }
        }
    }

    /**
     * 获取权限引导文案
     *
     * @param deniedPermissions
     * @return
     */
    private Spannable getPermissionGuideMsg(List<String> deniedPermissions) {
        if (null == deniedPermissions || deniedPermissions.isEmpty()) {
            return null;
        }
        boolean hasMatched = false;
        Spanny spanny = new Spanny("您需要在手机应用权限管理中，开启以下权限：");
        for (String permission : deniedPermissions) {
            switch (permission) {
                case Permission.READ_EXTERNAL_STORAGE:
                case Permission.WRITE_EXTERNAL_STORAGE:
                    if (!spanny.toString().contains("存储")) {
                        spanny.append("存储",
                                new ForegroundColorSpan(Color.parseColor("#3F51B5")),
                                new AbsoluteSizeSpan(ScreenUtils.sp2px(BaseApplication.getContext(), 17))
                        ).append("，");
                        hasMatched = true;
                    }
                    break;
                case Permission.READ_PHONE_STATE:
                    spanny.append("设备信息",
                            new ForegroundColorSpan(Color.parseColor("#3F51B5")),
                            new AbsoluteSizeSpan(ScreenUtils.sp2px(BaseApplication.getContext(), 17))
                    ).append("，");
                    hasMatched = true;
                    break;
                case Permission.ACCESS_FINE_LOCATION:
                case Permission.ACCESS_COARSE_LOCATION:
                    if (!spanny.toString().contains("位置信息")) {
                        spanny.append("位置信息",
                                new ForegroundColorSpan(Color.parseColor("#3F51B5")),
                                new AbsoluteSizeSpan(ScreenUtils.sp2px(BaseApplication.getContext(), 17))
                        ).append("，");
                        hasMatched = true;
                    }
                    break;
                case Permission.CAMERA:
                    spanny.append("相机",
                            new ForegroundColorSpan(Color.parseColor("#3F51B5")),
                            new AbsoluteSizeSpan(ScreenUtils.sp2px(BaseApplication.getContext(), 17))
                    ).append("，");
                    hasMatched = true;
                    break;
                case Permission.RECORD_AUDIO:
                    spanny.append("麦克风",
                            new ForegroundColorSpan(Color.parseColor("#3F51B5")),
                            new AbsoluteSizeSpan(ScreenUtils.sp2px(BaseApplication.getContext(), 17))
                    ).append("，");
                    hasMatched = true;
                    break;
                case Permission.CALL_PHONE:
                    spanny.append("打电话",
                            new ForegroundColorSpan(Color.parseColor("#3F51B5")),
                            new AbsoluteSizeSpan(ScreenUtils.sp2px(BaseApplication.getContext(), 17))
                    ).append("，");
                    hasMatched = true;
                    break;
                default:
                    break;
            }
        }
        if (!hasMatched) {
            //未匹配成功任一权限
            spanny = new Spanny("为保证系统功能正常运行，您需要在手机应用权限管理中, 开启相关权限。");
        } else {
            spanny.append("为保证系统功能正常运行。");
        }
        return spanny;
    }

    /**
     * app所有权限申请
     *
     * @param context
     * @param listener
     */
    public void requestAllPermissions(Context context, NormalPermissionListener listener) {
        requestPermission(context, new PermissionRequestListener() {
            @Override
            public void onGranted() {
                if (null != listener) {
                    listener.handleBusiness();
                }
            }

            @Override
            public void onDenied(List<String> data) {

            }
        }, true, ALL_PERMISSIONS);
    }

    /**
     * 录音权限申请
     *
     * @param context
     * @param listener
     */
    public void requestAudioRecordPermission(Context context, PermissionRequestListener listener) {
        requestPermission(context, listener, true,
                Permission.WRITE_EXTERNAL_STORAGE,
                Permission.READ_EXTERNAL_STORAGE,
                Permission.RECORD_AUDIO);
    }

    /**
     * 检测是否有定位相关权限
     * see {@link Permission#ACCESS_COARSE_LOCATION},
     * {@link Permission#ACCESS_FINE_LOCATION}
     */
    public boolean checkLocationPermission() {
        return AndPermission.hasPermissions(BaseApplication.getContext(), Permission.ACCESS_COARSE_LOCATION,
                Permission.ACCESS_FINE_LOCATION);
    }

    /**
     * GPS定位权限申请
     *
     * @param context
     * @param listener
     */
    public void requestGPSLocationPermission(Context context, PermissionRequestListener listener) {
        requestPermission(context,
                new PermissionRequestListener() {
                    @Override
                    public void onGranted() {
                        if (null != listener) {
                            listener.onGranted();
                        }
                    }

                    @Override
                    public void onDenied(List<String> data) {
                        if (null != listener) {
                            listener.onDenied(data);
                        }
                    }
                }, true, GPS_LOCATION_PERMISSIONS);
    }

    /**
     * 相机权限申请
     */
    public void requestCameraPermission(Context context, NormalPermissionListener listener) {
        requestPermission(context,
                new AndPermissionUtils.PermissionRequestListener() {
                    @Override
                    public void onGranted() {
                        if (null != listener) {
                            listener.handleBusiness();
                        }
                    }

                    @Override
                    public void onDenied(List<String> data) {

                    }
                }, true, Permission.CAMERA, Permission.WRITE_EXTERNAL_STORAGE);
    }

    /**
     * 相机权限申请及拍照
     */
    public void chooseImgFromCamera(Activity activity, File file, int requestCode) {
        if (null == activity || activity.isFinishing() || null == file) {
            return;
        }
        requestPermission(activity,
                new AndPermissionUtils.PermissionRequestListener() {
                    @Override
                    public void onGranted() {
                        if (null != activity && !activity.isFinishing()) {
                            Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                            // 判断存储卡是否可以用，可用进行存储
                            intent.putExtra(MediaStore.EXTRA_OUTPUT,
                                    SnailFileProviderUtils.getUriForFileWithPermission(activity, intent,
                                            file, true));
                            try {
                                activity.startActivityForResult(intent, requestCode);
                            } catch (SecurityException e) {
                            } catch (ActivityNotFoundException e) {
                            }
                        }
                    }

                    @Override
                    public void onDenied(List<String> data) {

                    }
                }, true, Permission.CAMERA, Permission.WRITE_EXTERNAL_STORAGE);
    }

    /**
     * 从相册选择图片
     *
     * @param activity
     * @param requestCode
     */
    public void chooseImgFromAlbum(Activity activity, int requestCode) {
        if (null == activity || activity.isFinishing()) {
            return;
        }
        requestPermission(activity, new PermissionRequestListener() {
            @Override
            public void onGranted() {
                if (null == activity || activity.isFinishing()) {
                    return;
                }
                Intent intent = new Intent(Intent.ACTION_PICK,
                        null);
                intent.setDataAndType(
                        MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                        "image/*");
                activity.startActivityForResult(intent, requestCode);
            }

            @Override
            public void onDenied(List<String> data) {

            }
        }, true, Permission.Group.STORAGE);
    }

    /**
     * app下载权限申请：存储权限
     *
     * @param context
     * @param listener
     */
    public void requestStoragePermissionGroup(Context context, NormalPermissionListener listener) {
        if (null == context) {
            return;
        }
        requestPermission(context, new PermissionRequestListener() {
            @Override
            public void onGranted() {
                if (null != listener) {
                    listener.handleBusiness();
                }
            }

            @Override
            public void onDenied(List<String> data) {

            }
        }, true, Permission.Group.STORAGE);
    }

    /**
     * 文件外部存储读写权限
     *
     * @param context
     * @param listener
     */
    public void requestStorageSinglePermission(Context context, String permission, NormalPermissionListener listener) {
        if (null == context) {
            return;
        }
        requestPermission(context, new PermissionRequestListener() {
            @Override
            public void onGranted() {
                if (null != listener) {
                    listener.handleBusiness();
                }
            }

            @Override
            public void onDenied(List<String> data) {

            }
        }, true, permission);
    }

    /**
     * APP升级包安装
     *
     * @param context
     */
    public void installApp(Context context, File file) {
        if (null == context || null == file || !file.exists()) {
            return;
        }
        checkStoragePermission(context, file);
    }

    /**
     * 安装前校验存储权限
     *
     * @param context
     * @param file
     */
    private void checkStoragePermission(final Context context, final File file) {
        if (null == context || null == file || !file.exists()) {
            return;
        }
        requestPermission(context, new PermissionRequestListener() {
            @Override
            public void onGranted() {
                //授权成功
                realInstallApp(context, file);
            }

            @Override
            public void onDenied(List<String> data) {
                //授权失败
            }
        }, false, Permission.Group.STORAGE);
    }

    /**
     * 安装App
     *
     * @param context
     * @param file
     */
    private void realInstallApp(Context context, File file) {
        if (null == context || null == file || !file.exists()) {
            return;
        }
        AndPermission.with(context)
                .install()
                .file(file)
                .onGranted(data -> {
                    //授权成功
                })
                .onDenied(data -> {
                    //授权失败
                })
                .start();
    }

    /**
     * 申请通知权限
     *
     * @param context
     * @param listener
     */
    public void requestNotification(Context context, NormalPermissionListener listener) {
        AndPermission.with(context)
                .notification()
                .permission()
                .onGranted(data -> {
                    //授权成功
                    if (null != listener) {
                        listener.handleBusiness();
                    }
                })
                .onDenied(data -> {
                    //未授权成功
                })
                .start();
    }

    /**
     * 是否有通知权限
     *
     * @param context
     * @return
     */
    public boolean hasNotificationPermission(Context context) {
        boolean hasNotifyPermission = true;
        if (null == context) {
            return hasNotifyPermission;
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            hasNotifyPermission = getNotificationManager(context).areNotificationsEnabled();
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            hasNotifyPermission = reflectionOps(context, OP_POST_NOTIFICATION);
        }
        return hasNotifyPermission;
    }

    private NotificationManager getNotificationManager(Context context) {
        if (mNotificationManager == null) {
            mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
        }
        return mNotificationManager;
    }

    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    private boolean reflectionOps(Context context, String opFieldName) {
        int uid = context.getApplicationInfo().uid;
        try {
            Class<AppOpsManager> appOpsClass = AppOpsManager.class;
            Method method = appOpsClass.getMethod(CHECK_OP_NO_THROW, Integer.TYPE, Integer.TYPE, String.class);
            Field opField = appOpsClass.getDeclaredField(opFieldName);
            int opValue = (int) opField.get(Integer.class);
            int result = (int) method.invoke(getAppOpsManager(context), opValue, uid, context.getPackageName());
            return result == AppOpsManager.MODE_ALLOWED || result == MODE_ASK;
        } catch (Throwable e) {
            return true;
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    private AppOpsManager getAppOpsManager(Context context) {
        if (mAppOpsManager == null) {
            mAppOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
        }
        return mAppOpsManager;
    }

    /**
     * 申请设备权限
     *
     * @param context
     * @param listener
     */
    public void requestDeviceInfoPermission(Context context, NormalPermissionListener listener) {
        if (null == context) {
            return;
        }
        requestPermission(context,
                new PermissionRequestListener() {
                    @Override
                    public void onGranted() {
                        if (null != listener) {
                            listener.handleBusiness();
                        }
                    }

                    @Override
                    public void onDenied(List<String> data) {

                    }
                }, false, Permission.READ_PHONE_STATE);
    }

    private int getTargetSdkVersion() {
        if (mTargetSdkVersion < Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
            mTargetSdkVersion = BaseApplication.getContext().getApplicationInfo().targetSdkVersion;
        }
        return mTargetSdkVersion;
    }

    private String getPackageName() {
        if (mPackageName == null) {
            mPackageName = BaseApplication.getContext().getApplicationContext().getPackageName();
        }
        return mPackageName;
    }

    /**
     * 是否有存储权限
     *
     * @return
     */
    public boolean hasStoragePermission() {
        return AndPermission.hasPermissions(BaseApplication.getContext(), Permission.WRITE_EXTERNAL_STORAGE
                , Permission.READ_EXTERNAL_STORAGE);
    }

    /**
     * 是否可以写设置
     *
     * @return
     */
    public boolean hasWriteSettingPermission() {
        boolean hasWriteSettingPermission = true;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            Context context = BaseApplication.getContext();
            if (getTargetSdkVersion() >= Build.VERSION_CODES.M) {
                hasWriteSettingPermission = Settings.System.canWrite(context);
            } else {
                hasWriteSettingPermission = reflectionOps(context, OP_WRITE_SETTINGS);
            }
        }
        return hasWriteSettingPermission;
    }

    /**
     * 申请写系统设置权限
     *
     * @param activity
     */
    public void requestWriteSettingPermission(Activity activity, PermissionRequestListener listener) {
        if (ActivityManagerUtil.getInstance().isActivityDestroy(activity)) {
            return;
        }
        AndPermission.with(activity)
                .setting()
                .write()
                // 准备方法，和 okhttp 的拦截器一样，在请求权限之前先运行改方法，已经拥有权限不会触发该方法
                .rationale((context, permissions, executor) -> {
                    // 此处可以选择显示提示弹窗
                    executor.execute();
                })
                // 用户给权限了
                .onGranted(permissions -> {
                    if (null != listener) {
                        listener.onGranted();
                    }
                })
                // 用户拒绝权限，包括不再显示权限弹窗也在此列
                .onDenied(permissions -> {
                    //进入设置页让用户授权
                    if (null != listener) {
                        listener.onDenied(new ArrayList<>());
                    }
                })
                .start();
    }

    /**
     * 统一的悬浮弹框授权申请
     *
     * @param context
     * @param listener
     */
    public void requestAlertWindowPermission(Context context, boolean showRationale,
                                             PermissionRequestListener listener) {
        if (checkFloatPermission(context)) {
            if (null != listener) {
                listener.onGranted();
            }
            return;
        }
        AndPermission.with(context)
                .overlay()
                .rationale((context1, data, executor) -> {
                    //未授权，弹框提示
                    if (!showRationale) {
                        //不需要弹框的，直接跳转设置引导用户授权
                        executor.execute();
                        return;
                    }
                    if (context instanceof Activity && !((Activity) context).isFinishing()) {
                        if (null == mOverlayGuideDialog || null == mOverlayGuideDialog.getDialog()) {
                            mOverlayGuideDialog = new PermissionDialog(context, -1)
                                    .setDialogLayout(R.layout.dialog_permission_guide)
                                    .setCancelable(false)
                                    .setDismissListener(dialog -> {
                                        //对话框关闭监听
                                        //跳转设置引导用户授权
                                        executor.execute();
                                        if (null != mOverlayGuideDialog) {
                                            mOverlayGuideDialog.resetDialogView();
                                            mOverlayGuideDialog = null;
                                        }
                                    });
                        }
                        mOverlayGuideDialog.setDialogViewListener((v, baseDialog) -> {
                            //设置view内容
                            Spanny alertDialogMsg = new Spanny("您需要开启:");
                            alertDialogMsg.append("浮窗",
                                    new ForegroundColorSpan(Color.parseColor("#3F51B5")),
                                    new AbsoluteSizeSpan(ScreenUtils.sp2px(BaseApplication.getContext(), 17))
                            ).append("权限, 为保障系统功能正常运行");
                            TextView contentTv = v.findViewById(R.id.dialog_content);
                            contentTv.setText(alertDialogMsg);
                            //对话框view绑定事件监听
                            v.findViewById(R.id.posButton).setOnClickListener(v1 -> {
                                baseDialog.dismiss();
                            });
                        }).show();
                    }
                })
                .onGranted((data) -> {
                    if (null != listener) {
                        listener.onGranted();
                    }
                })
                .onDenied(data -> {
                    if (null != listener) {
                        listener.onDenied(null);
                    }
                }).start();
    }

    /**
     * 判断悬浮窗权限是否开启
     *
     * @param context
     * @return
     */
    public boolean checkFloatPermission(Context context) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT)
            return true;
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
            try {
                Class cls = Class.forName("android.content.Context");
                Field declaredField = cls.getDeclaredField("APP_OPS_SERVICE");
                declaredField.setAccessible(true);
                Object obj = declaredField.get(cls);
                if (!(obj instanceof String)) {
                    return false;
                }
                String str2 = (String) obj;
                obj = cls.getMethod("getSystemService", String.class).invoke(context, str2);
                cls = Class.forName("android.app.AppOpsManager");
                Field declaredField2 = cls.getDeclaredField("MODE_ALLOWED");
                declaredField2.setAccessible(true);
                Method checkOp = cls.getMethod("checkOp", Integer.TYPE, Integer.TYPE, String.class);
                int result = (Integer) checkOp.invoke(obj, 24, Binder.getCallingUid(), context.getPackageName());
                return result == declaredField2.getInt(cls);
            } catch (Exception e) {
                return false;
            }
        } else {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                AppOpsManager appOpsMgr = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
                if (appOpsMgr == null)
                    return false;
                int mode = appOpsMgr.checkOpNoThrow("android:system_alert_window", android.os.Process.myUid(), context
                        .getPackageName());
                return mode == AppOpsManager.MODE_ALLOWED || mode == AppOpsManager.MODE_IGNORED;
            } else {
                return Settings.canDrawOverlays(context);
            }
        }
    }

    /**
     * 部分机型activity退出时窗体泄漏
     */
    public void dismissPermissionDialog() {
        if (null != mPermissionGuideDialog && mPermissionGuideDialog.isShowing()) {
            mPermissionGuideDialog.dismiss();
            mPermissionGuideDialog = null;
        }
    }

    /**
     * 跳转到指定应用的指定页面
     */
    private void showActivity(Activity activity, @NonNull String packageName, @NonNull String activityDir) {
        Intent intent = new Intent();
        intent.setComponent(new ComponentName(packageName, activityDir));
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        activity.startActivity(intent);
    }

    /**
     * 权限申请监听
     */
    public interface PermissionRequestListener {
        void onGranted(); //允许获得权限后操作

        void onDenied(List<String> data); //拒绝权限后操作
    }

    /**
     * 正常回调监听，用于处理正常业务逻辑(授权后的回调)
     */
    public interface NormalPermissionListener {
        /**
         * 根据需求回调正常的业务逻辑，比如授权或者未授权等根据需求是否做正常的业务逻辑
         */
        void handleBusiness();
    }
}
